package com.zhang;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Optional;

public class JDK8LocalDataTimeTest {

    public static void main(String[] args) throws Exception {
//        test4();
//        System.out.println("=========================================");
        test5();
//        System.out.println("=========================================");
//        test6();
//        System.out.println("=========================================");
//        test7();
//        System.out.println("=========================================");
//        test8();
//        test9();
    }

    public static void test() {
        // 从默认时区的系统时钟获取当前的日期时间。不用考虑时区差
        LocalDateTime date = LocalDateTime.now();
        //2018-07-15T14:22:39.759
        System.out.println(date);

        System.out.println(date.getYear());
        System.out.println(date.getMonthValue());
        System.out.println(date.getDayOfMonth());
        System.out.println(date.getHour());
        System.out.println(date.getMinute());
        System.out.println(date.getSecond());
        System.out.println(date.getNano());

        // 手动创建一个LocalDateTime实例
        LocalDateTime date2 = LocalDateTime.of(2017, 12, 17, 9, 31, 31, 31);
        System.out.println(date2);
        // 进行加操作，得到新的日期实例
        LocalDateTime date3 = date2.plusDays(12);
        System.out.println(date3);
        // 进行减操作，得到新的日期实例
        LocalDateTime date4 = date3.minusYears(2);
        System.out.println(date4);


    }

    public static void test1() {
        // 时间戳  1970年1月1日00：00：00 到某一个时间点的毫秒值
        // 默认获取UTC时区
        Instant ins = Instant.now();
        System.out.println(ins);
        Instant instant = LocalDateTime.now().toInstant(ZoneOffset.of("+8"));
        System.out.println("instant = " + instant);
        System.out.println(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        System.out.println(System.currentTimeMillis());

        System.out.println(Instant.now().toEpochMilli());
        System.out.println(Instant.now().atOffset(ZoneOffset.ofHours(8)).toInstant().toEpochMilli());
    }

    public static void test2() {
        // DateTimeFormatter: 格式化时间/日期
        // 自定义格式
        LocalDateTime ldt = LocalDateTime.now();

        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        String strDate1 = ldt.format(formatter);
        String strDate = formatter.format(ldt);


        System.out.println(strDate);
        System.out.println(strDate1);

        // 使用api提供的格式
        DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE;

        LocalDateTime ldt2 = LocalDateTime.now();
        String strDate3 = dtf.format(ldt2);
        System.out.println(strDate3);

        // 解析字符串to时间
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime time = LocalDateTime.now();
        String localTime = df.format(time);
        LocalDateTime ldt4 = LocalDateTime.parse("2017-09-28 17:07:05", df);
        System.out.println("LocalDateTime转成String类型的时间：" + localTime);
        System.out.println("String类型的时间转成LocalDateTime：" + ldt4);
        Date date = new Date();
        System.out.println("date = " + date);
    }

    public static void test3() {
        Date date = new Date();
        System.out.println("date = " + date);
        Calendar instance = Calendar.getInstance();
        int YEAR = instance.get(Calendar.YEAR);
        System.out.println("YEAR = " + YEAR);
        int MONTH = instance.get(Calendar.MONTH);
        System.out.println("MONTH = " + MONTH);
        int i = instance.get(Calendar.DAY_OF_MONTH);
        System.out.println("i = " + i);
        int i1 = instance.get(Calendar.DAY_OF_WEEK);
        System.out.println("i1 = " + i1);
        int i2 = instance.get(Calendar.DAY_OF_WEEK_IN_MONTH);
        System.out.println("i2 = " + i2);


    }

    /*
     * Optional.of(T t); // 创建一个Optional实例
     * Optional.empty(); // 创建一个空的Optional实例
     * Optional.ofNullable(T t); // 若T不为null，创建一个Optional实例，否则创建一个空实例
     * isPresent();    // 判断是够包含值
     * orElse(T t);   //如果调用对象包含值，返回该值，否则返回T
     * orElseGet(Supplier s);  // 如果调用对象包含值，返回该值，否则返回s中获取的值
     * map(Function f): // 如果有值对其处理，并返回处理后的Optional，否则返回Optional.empty();
     * flatMap(Function mapper);// 与map类似。返回值是Optional
     * <p>
     * 总结：Optional.of(null)  会直接报NPE
     */


    public static void test4() {
        System.out.println("test4");

        Optional<Object> op = Optional.empty();
        System.out.println(op);
        // No value present
        System.out.println(op.get());
    }

    public static void test5() {
        System.out.println("test5");

        Optional<Employee> op = Optional.ofNullable(new Employee("lisi", 33, 131.42, Employee.Status.FREE.getCode()));
        System.out.println(op.get());
        System.out.println(op.isPresent());
        Optional<Object> op2 = Optional.ofNullable(null);
        System.out.println(op2);
        System.out.println(op2.isPresent());

        // System.out.println(op2.get());
    }

    public static void test6() {
        System.out.println("test6");

        Optional<Employee> op1 = Optional.ofNullable(new Employee("张三", 11, 11.33, Employee.Status.VOCATION.getCode()));
        Optional<Employee> employee = Optional.ofNullable(new Employee());
        System.out.println(op1.orElse(new Employee()));
        System.out.println(op1.orElse(null));
        System.out.println(employee.orElse(new Employee()));
        System.out.println(employee.orElse(null));
    }

    public static void test7() {
        System.out.println("test7");
        Optional<Employee> op1 = Optional.ofNullable(null);

//        op1 = Optional.empty();
        Employee employee = op1.orElseGet(() -> new Employee("田七", 11, 12.31, Employee.Status.BUSY.getCode()));
        System.out.println(employee);
    }

    public static void test8() {
        System.out.println("test8");

        Optional<Employee> op1 = Optional.of(new Employee("田七", 11, 12.31, Employee.Status.BUSY.getCode()));
        Optional<Integer> integer = op1.map((e) -> e.getSalary());
        Optional<String> s = op1.map((e) -> {
            return e.getName();
        });
        String s1 = s.get();
        System.out.println("s1 = " + s1);
    }

    public static void test9() throws Exception {
        Student student = new Student(null, 3);
//        if (student == null || isEmpty(student.getName())) {
//            throw new Exception();
//        }
        String name = student.getName();
        // 业务省略...

        // 使用Optional改造
        Optional<Student> student1 = Optional.ofNullable(student);
        System.out.println("student1 = " + student1);

        Optional<Student> student2 = student1.filter(s -> !isEmpty(s.getName()));
        System.out.println("student2 = " + student2);


        Student student3 = student2.orElseThrow(() -> new Exception());
        System.out.println("student3 = " + student3);
    }

    public static boolean isEmpty(CharSequence str) {
        return str == null || str.length() == 0;
    }

}